#pragma once

#include "TinyMsgHeader.h"

namespace TinyCC{
	namespace msg{
		class CTinyMsg
		{
		private:
			enum{ FIXED_MSG_LENGTH = 1024	};
		public:
			CTinyMsg();
			CTinyMsg(const CTinyMsg & tinymsg);
			virtual ~CTinyMsg();

			void clear();

			//process MsgHead		
			const char* getSourceIP();
			void setSourceIP(const char* ip);
			
			WORD getSourcePort();
			inline void setSourcePort(WORD port){m_msgHead.m_sourcePort = port;}

			int getSocketID(){return m_socketID;}
			void setSocketID(int sid){m_socketID = sid;}
			
			//Set message Index
			inline void setMsgIndex(WORD msgIndex){m_msgHead.m_msgIndex = msgIndex;}
			
			//set message Item
			inline void setMsgItem(WORD msgItem){m_msgHead.m_msgItem = msgItem;}

			//get message Item                                        
			inline WORD getMsgItem(){return m_msgHead.m_msgItem;}

			//get message Index
			inline WORD getMsgIndex() const{return m_msgHead.m_msgIndex;}

			//end process MsgHead

			//process default params

			//push_back param func,
			//char * is equal to std::string,
			//CTinyMetaElement* means special value but not std::string
			long pushBackDefaultParam(const char* value);
			long pushBackDefaultParam(std::string& value);
			long pushBackDefaultParam(CTinyMetaElement* value);
			bool setDefaultParam(int index,CTinyMetaElement* value);
			bool setDefaultParam(int index,std::string& value);
			bool setDefaultParam(int index,char* value);

			//retrive default param info
			int getDefaultParamCount();

			CTinyMetaElement* getDefaultParamByIndex(int defaultParamIndex);
			bool getDefaultParamByIndex(int defaultParamIndex, std::string& value);

			//end process default params

			//process External params
			//char * is equal to std::string,
			//CTinyMetaElement* means special value but not std::string

			long pushExternalParamByKey(int epindex,CTinyMetaElement* key,CTinyMetaElement* value);
			long pushExternalParamByKey(int epindex,const char* key,const char* value);
			long pushExternalParamByKey(int epindex,std::string& key,std::string& value);


			//retrieve External param count and param value count in a paramkey
			int getExternalParamKeyCountByIndex(int epindex);
			int getExternalParamValueCountByKey(int epindex, const char* key);

			//retrieve key and value func
			CTinyMetaElement* getExternalParamValueByEmunator(int epindex,std::string& key,int externalParamValueIndex);
			CTinyMetaElement* getExternalParamValueByEmunator(int epindex,const char* key,int externalParamValueIndex);
			bool getExternalParamValueByEmunator(int epindex,std::string& key,int externalParamValueIndex,std::string& value);
			bool getExternalParamValueByEmunator(int epindex,const char* key,int externalParamValueIndex, std::string& value);

			CTinyMetaElement* getExternalParamValueByEmunator(int epindex,CTinyMetaElement* key,int externalParamValueIndex);

			//reserve four func for retrieve info by iterator		
			int  _EnumnerateEPValueCountByKey(int epindex,int externalParamIndex);
			CTinyMetaElement* _EnumnerateEPValueByIndex(int epindex,int keyIndex,int externalParamValueIndex);
			bool _EnumnerateEPKeyByIndex(int epindex,int keyIndex,std::string& key);
			CTinyMetaElement* _EnumnerateEPKeyByIndex(int epindex,int keyIndex);
			CTinyMetaElement*  _EnumnerateEPValueByEnumnator(int epindex,int keyIndex,int externalParamValueIndex);
			bool _EnumnerateEPValueByEnumnator(int epindex,int keyIndex,int externalParamValueIndex, std::string& value);
			//end reserve

			int getExternalParamMapSize(){ return (int)m_ExternalParamsMap.size();} 
			
			//finished later
			const char* serialize(long& length);
			bool deSerialize(const char* pMsg,long length);

		private:
			const CTinyMsg & operator= (const CTinyMsg & tinymsg){};
			void _writeCheckSum();
			BOOL _verifyCheckSum();
			char m_sourceIP[128];
			int m_socketID;
			char* m_pMsgData;		// Head address of data buffer
			std::list<CTinyMetaElement*> m_defaultParams;
			std::map<int,CTinyParamMap*> m_ExternalParamsMap;
			CTinyMsgHeader m_msgHead;
			char m_Fixedbuffer[FIXED_MSG_LENGTH];
		};

	}
}
